"""
售气系统
实现令牌生成和交易管理
"""

import time
from typing import Dict, Any, Optional, List
from .transaction import TransactionManager, Transaction
from ..sts import STSProtocol, STSCrypto, STSUtils


class VendingSystem:
    """售气系统类"""
    
    def __init__(self, crypto: Optional[STSCrypto] = None):
        """
        初始化售气系统
        
        Args:
            crypto: 加密模块实例
        """
        self.crypto = crypto or STSCrypto()
        self.protocol = STSProtocol(self.crypto)
        self.transaction_manager = TransactionManager()
        self.utils = STSUtils()
        
        # 系统配置
        self.min_amount = 100  # 最小充值金额（分）
        self.max_amount = 99999999  # 最大充值金额（分）
        self.gas_rate = 2.5  # 气价（元/立方米）
        
        # 操作员信息
        self.current_operator = None
        self.operator_session = None
    
    def login_operator(self, operator_id: str, password: str) -> Dict[str, Any]:
        """
        操作员登录
        
        Args:
            operator_id: 操作员ID
            password: 密码
            
        Returns:
            登录结果
        """
        # 简单的密码验证（实际应用中应该使用数据库和加密）
        if password == "123456":  # 示例密码
            self.current_operator = operator_id
            self.operator_session = {
                'operator_id': operator_id,
                'login_time': int(time.time()),
                'session_id': f"OP_{int(time.time())}"
            }
            
            return {
                'success': True,
                'operator_id': operator_id,
                'session_id': self.operator_session['session_id'],
                'login_time': self.operator_session['login_time']
            }
        else:
            return {
                'success': False,
                'error': 'Invalid operator credentials'
            }
    
    def logout_operator(self) -> Dict[str, Any]:
        """
        操作员登出
        
        Returns:
            登出结果
        """
        if not self.current_operator:
            return {
                'success': False,
                'error': 'No operator logged in'
            }
        
        session_info = self.operator_session
        self.current_operator = None
        self.operator_session = None
        
        return {
            'success': True,
            'operator_id': session_info['operator_id'],
            'session_duration': int(time.time()) - session_info['login_time']
        }
    
    def generate_token(self, meter_id: str, amount: int, 
                      payment_method: str = "CASH") -> Dict[str, Any]:
        """
        生成充值令牌
        
        Args:
            meter_id: 表计ID
            amount: 充值金额（分）
            payment_method: 支付方式
            
        Returns:
            令牌生成结果
        """
        if not self.current_operator:
            return {
                'success': False,
                'error': 'Operator not logged in'
            }
        
        if not self.utils.validate_meter_id(meter_id):
            return {
                'success': False,
                'error': 'Invalid meter ID format'
            }
        
        if not self.utils.validate_amount(amount):
            return {
                'success': False,
                'error': 'Invalid amount'
            }
        
        if amount < self.min_amount or amount > self.max_amount:
            return {
                'success': False,
                'error': f'Amount must be between {self.min_amount/100} and {self.max_amount/100} yuan'
            }
        
        # 创建交易记录
        transaction = self.transaction_manager.create_transaction(
            meter_id, amount, "RECHARGE"
        )
        
        # 设置交易详情
        transaction.set_operator(self.current_operator)
        transaction.set_payment_method(payment_method)
        
        try:
            # 启动STS协议会话
            session_result = self.protocol.start_session(meter_id)
            
            if not session_result['success']:
                transaction.set_status("FAILED", session_result['error'])
                return session_result
            
            # 生成令牌
            token_result = self.protocol.generate_recharge_token(amount)
            
            if not token_result['success']:
                transaction.set_status("FAILED", token_result['error'])
                return token_result
            
            # 设置令牌并完成交易
            token = token_result['token']
            transaction.set_token(token)
            transaction.set_status("COMPLETED")
            
            # 结束会话
            self.protocol.end_session()
            
            return {
                'success': True,
                'transaction_id': transaction.transaction_id,
                'token': token,
                'meter_id': meter_id,
                'amount': amount,
                'amount_formatted': token_result['amount_formatted'],
                'payment_method': payment_method,
                'operator_id': self.current_operator,
                'timestamp': transaction.timestamp,
                'transfer_counter': token_result['transfer_counter']
            }
            
        except Exception as e:
            transaction.set_status("ERROR", str(e))
            return {
                'success': False,
                'error': f'Token generation failed: {str(e)}'
            }
    
    def verify_token(self, token: str, meter_id: str) -> Dict[str, Any]:
        """
        验证令牌
        
        Args:
            token: 令牌字符串
            meter_id: 表计ID
            
        Returns:
            验证结果
        """
        if not self.current_operator:
            return {
                'success': False,
                'error': 'Operator not logged in'
            }
        
        # 启动STS协议会话
        session_result = self.protocol.start_session(meter_id)
        
        if not session_result['success']:
            return session_result
        
        # 验证令牌
        verify_result = self.protocol.verify_recharge_token(token)
        
        # 结束会话
        self.protocol.end_session()
        
        return verify_result
    
    def get_transaction(self, transaction_id: str) -> Dict[str, Any]:
        """
        获取交易信息
        
        Args:
            transaction_id: 交易ID
            
        Returns:
            交易信息
        """
        transaction = self.transaction_manager.get_transaction(transaction_id)
        
        if transaction:
            return {
                'success': True,
                'transaction': transaction.to_dict()
            }
        else:
            return {
                'success': False,
                'error': 'Transaction not found'
            }
    
    def get_transactions_by_meter(self, meter_id: str, 
                                 limit: int = 50) -> Dict[str, Any]:
        """
        获取指定表计的交易历史
        
        Args:
            meter_id: 表计ID
            limit: 返回数量限制
            
        Returns:
            交易历史
        """
        transactions = self.transaction_manager.get_transactions_by_meter(meter_id, limit)
        
        return {
            'success': True,
            'meter_id': meter_id,
            'transactions': [txn.to_dict() for txn in transactions],
            'count': len(transactions)
        }
    
    def get_recent_transactions(self, hours: int = 24, 
                               limit: int = 100) -> Dict[str, Any]:
        """
        获取最近的交易
        
        Args:
            hours: 时间范围（小时）
            limit: 返回数量限制
            
        Returns:
            最近交易列表
        """
        transactions = self.transaction_manager.get_recent_transactions(hours, limit)
        
        return {
            'success': True,
            'period_hours': hours,
            'transactions': [txn.to_dict() for txn in transactions],
            'count': len(transactions)
        }
    
    def get_transaction_statistics(self, hours: int = 24) -> Dict[str, Any]:
        """
        获取交易统计
        
        Args:
            hours: 统计时间范围（小时）
            
        Returns:
            统计信息
        """
        stats = self.transaction_manager.get_transaction_statistics(hours)
        
        return {
            'success': True,
            'statistics': stats
        }
    
    def calculate_gas_volume(self, amount: int) -> float:
        """
        根据金额计算气量
        
        Args:
            amount: 金额（分）
            
        Returns:
            气量（立方米）
        """
        return (amount / 100) / self.gas_rate
    
    def calculate_amount_from_volume(self, volume: float) -> int:
        """
        根据气量计算金额
        
        Args:
            volume: 气量（立方米）
            
        Returns:
            金额（分）
        """
        return int(volume * self.gas_rate * 100)
    
    def set_gas_rate(self, rate: float) -> Dict[str, Any]:
        """
        设置气价
        
        Args:
            rate: 新气价（元/立方米）
            
        Returns:
            设置结果
        """
        if rate <= 0:
            return {
                'success': False,
                'error': 'Gas rate must be positive'
            }
        
        old_rate = self.gas_rate
        self.gas_rate = rate
        
        return {
            'success': True,
            'old_rate': old_rate,
            'new_rate': rate,
            'message': f'Gas rate updated from {old_rate} to {rate} yuan/m³'
        }
    
    def get_system_info(self) -> Dict[str, Any]:
        """
        获取系统信息
        
        Returns:
            系统信息
        """
        return {
            'system_name': 'STS Gas Vending System',
            'version': '1.0.0',
            'current_operator': self.current_operator,
            'gas_rate': self.gas_rate,
            'min_amount': self.min_amount,
            'max_amount': self.max_amount,
            'protocol_info': self.protocol.get_protocol_info(),
            'transaction_count': self.transaction_manager.transaction_counter
        }
    
    def cleanup_old_data(self, days: int = 30) -> Dict[str, Any]:
        """
        清理旧数据
        
        Args:
            days: 保留天数
            
        Returns:
            清理结果
        """
        cleaned_count = self.transaction_manager.cleanup_old_transactions(days)
        
        return {
            'success': True,
            'cleaned_transactions': cleaned_count,
            'retention_days': days,
            'message': f'Cleaned {cleaned_count} old transactions'
        }
